---
title: 라우팅
description: Astro 라우팅 소개
i18nReady: true
---
import { FileTree } from '@astrojs/starlight/components';
import RecipeLinks from "~/components/RecipeLinks.astro"
import Since from '~/components/Since.astro'
import ReadMore from '~/components/ReadMore.astro'

Astro는 프로젝트 `src/pages/` 디렉터리의 파일 레이아웃을 기반으로 빌드 URL을 생성하기 위해 **파일 기반 라우팅**을 사용합니다.

## 페이지 간 탐색

Astro는 라우트 간 탐색을 위해 표준 HTML [`<a>` 요소](https://developer.mozilla.org/ko/docs/Web/HTML/Element/a)를 사용합니다. 제공되는 프레임워크 특정 `<Link>` 컴포넌트는 없습니다.

```astro title="src/pages/index.astro"
<p>Astro에 대해 더 <a href="/about/">자세히</a> 알아보세요!</p>

<!-- `base: "/docs"`가 구성된 경우 -->
<p><a href="/docs/reference/">참조</a> 섹션에서 더 자세히 알아보세요!</p>
```

## 정적 라우트

`src/pages/` 디렉터리의 `.astro` [페이지 컴포넌트](/ko/basics/astro-pages/)와 Markdown 및 MDX 파일 (`.md`, `.mdx`)은 **자동으로 웹사이트의 페이지가 됩니다**. 각 페이지의 라우트는 `src/pages/` 디렉터리의 경로 및 파일 이름에 해당합니다.

```diff
# 예시: 정적 라우트
src/pages/index.astro        -> mysite.com/
src/pages/about.astro        -> mysite.com/about
src/pages/about/index.astro  -> mysite.com/about
src/pages/about/me.astro     -> mysite.com/about/me
src/pages/posts/1.md         -> mysite.com/posts/1
```

:::tip
Astro 프로젝트에서 유지 관리할 별도의 "라우팅 구성"은 없습니다! `src/pages/` 디렉터리에 파일을 추가하면 새 라우트가 자동으로 생성됩니다. 정적 빌드에서 [`build.format`](/ko/reference/configuration-reference/#buildformat) 구성 옵션을 사용하여 파일 출력 형식을 사용자 정의할 수 있습니다.
:::

## 동적 라우트

Astro 페이지 파일은 파일 이름에 동적 라우트 매개변수를 지정하여 일치하는 여러 페이지를 생성할 수 있습니다. 예를 들어, `src/pages/authors/[author].astro`는 블로그의 모든 작성자에 대한 바이오 페이지를 생성합니다. `author`는 페이지에서 액세스할 수 있는 _매개변수가_ 됩니다.

Astro의 기본 정적 출력 모드에서는 이러한 페이지가 빌드 시 생성되므로 해당 파일을 가져오는 `author` 목록을 미리 결정해야 합니다. SSR 모드에서는 일치하는 모든 라우트에 대한 요청 시 페이지가 생성됩니다.

### 정적 (SSG) 모드

모든 라우트는 빌드 시 결정되어야 하므로 동적 라우트는 `params` 속성이 있는 객체의 배열을 반환하는 `getStaticPaths()`를 내보내야 합니다. 이러한 각 객체는 해당되는 라우트를 생성합니다.

`[dog].astro`는 파일 이름에 동적 `dog` 매개변수를 정의하므로 `getStaticPaths()`에서 반환된 객체는 `params`에 `dog`를 포함해야 합니다. 그러면 페이지는 `Astro.params`를 사용하여 이 매개변수에 액세스할 수 있습니다.

```astro title="src/pages/dogs/[dog].astro"
---
export function getStaticPaths() {
  return [
    { params: { dog: "clifford" }},
    { params: { dog: "rover" }},
    { params: { dog: "spot" }},
  ];
}

const { dog } = Astro.params;
---
<div>{dog}는 귀여운 강아지입니다!</div>
```

이는 해당 강아지 이름을 각각 표시하는 세 개의 페이지 `/dogs/clifford`, `/dogs/rover` 및 `/dogs/spot`을 생성합니다.

파일 이름은 여러 매개변수를 포함할 수 있으며, 이 매개변수는 모두 `getStaticPaths()`의 `params` 객체에 포함되어야 합니다.

```astro title="src/pages/[lang]-[version]/info.astro"
---
export function getStaticPaths() {
  return [
    { params: { lang: "en", version: "v1" }},
    { params: { lang: "fr", version: "v2" }},
  ];
}

const { lang, version } = Astro.params;
---
```

이렇게 하면 `/en-v1/info` 및 `/fr-v2/info`가 생성됩니다.

매개변수는 경로의 별도 부분에 포함될 수 있습니다. 예를 들어, 위의 동일한 `getStaticPaths()`를 사용하는 파일 `src/pages/[lang]/[version]/info.astro`는 `/en/v1/info` 및 `/fr/v2/info` 라우트를 생성합니다.

#### `params` 디코딩

`getStaticPaths()` 함수가 반한하는 `params`는 디코딩되지 않습니다. 매개변수 값을 디코딩해야 하는 경우 [`decodeURI()`](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/decodeURI)를 사용하세요.

```astro title="src/pages/[slug].astro"
--- 
export function getStaticPaths() {
  return [
    { params: { slug: decodeURI("%5Bpage%5D") }}, // "[page]"로 디코딩됩니다.
  ]
}
---
```

<ReadMore>[`getStaticPaths()`](/ko/reference/routing-reference/#getstaticpaths)에 대해 자세히 알아보세요.</ReadMore>

<RecipeLinks slugs={["ko/recipes/i18n"]} />

#### 나머지 매개변수

URL 라우팅에서 더 많은 유연성이 필요한 경우 `.astro` 파일 이름에 [나머지 매개변수](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/rest_parameters) (`[...path]`)를 사용하여 모든 깊이의 파일 경로와 일치시킬 수 있습니다.

```astro title="src/pages/sequences/[...path].astro"
---
export function getStaticPaths() {
  return [
    { params: { path: "one/two/three" }},
    { params: { path: "four" }},
    { params: { path: undefined }}
  ]
}

const { path } = Astro.params;
---
```

이렇게 하면 `/sequences/one/two/three`, `/sequences/four` 및 `/sequences`가 생성됩니다. (나머지 매개변수를 `undefined`로 설정하면 최상위 페이지와 일치할 수 있습니다.)

나머지 매개변수는 **명명된 다른 매개변수**와 함께 사용할 수 있습니다. 예를 들어 GitHub의 파일 뷰어는 다음 동적 라우트로 나타낼 수 있습니다.

```
/[org]/[repo]/tree/[branch]/[...file]
```

이 예시에서 `/withastro/astro/tree/main/docs/public/favicon.svg`에 대한 요청은 다음과 같은 명명된 매개변수로 분할됩니다.

```js
{
	org: "withastro",
	repo: "astro",
	branch: "main",
	file: "docs/public/favicon.svg"
}
```

#### 예시: 여러 레벨의 동적 페이지

다음 예시에서 나머지 매개변수 (`[...slug]`)와 `getStaticPaths()`의 [`props`](/ko/reference/routing-reference/#props를-사용한-데이터-전달) 기능을 사용하여 다양한 깊이의 슬러그에 대한 페이지를 생성합니다.

```astro title="src/pages/[...slug].astro"
---
export function getStaticPaths() {
  const pages = [
    {
      slug: undefined,
      title: "Astro 스토어",
      text: "Astro 스토어에 오신 것을 환영합니다!",
    },
    {
      slug: "products",
      title: "Astro 제품",
      text: "여러분을 위한 다양한 제품이 준비되어 있습니다.",
    },
    {
      slug: "products/astro-handbook",
      title: "궁극적인 Astro 핸드북",
      text: "Astro를 배우고 싶다면 이 책을 꼭 읽어야 합니다.",
    },
  ];
  
  return pages.map(({ slug, title, text }) => {
    return {
      params: { slug },
      props: { title, text },
    };
  });
}

const { title, text } = Astro.props;
---
<html>
  <head>
    <title>{title}</title>
  </head>
  <body>
    <h1>{title}</h1>
    <p>{text}</p>
  </body>
</html>
```

### 요청 시 렌더링되는 동적 라우트

어댑터를 사용하여 [요청 시 렌더링](/ko/guides/on-demand-rendering/)을 수행하는 경우, 동적 라우트는 동일한 방식으로 정의됩니다. 임의의 문자열 또는 경로와 일치하도록 파일 이름에 `[param]` 또는 `[...path]` 대괄호를 포함합니다. 그러나 라우트는 더 이상 미리 빌드되지 않으므로 일치하는 모든 라우트에 페이지가 제공됩니다. 이러한 라우트는 "정적" 라우트가 아니므로 `getStaticPaths`를 사용하면 안됩니다.

요청 시 렌더링되는 라우트의 경우 파일 이름에 스프레드 표기법을 사용하는 나머지 매개변수를 하나만 사용할 수 있습니다. (예: `src/pages/[locale]/[...slug].astro` 또는 `src/pages/[...locale]/[slug].astro`는 사용할 수 있지만, `src/pages/[...locale]/[...slug].astro`는 사용할 수 없습니다.)

```astro title="src/pages/resources/[resource]/[id].astro"
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
const { resource, id } = Astro.params;
---
<h1>{resource}: {id}</h1>
```

이 페이지는 `resource` 및 `id`의 모든 값에 대해 제공됩니다. 예: `resources/users/1`, `resources/colors/blue` 등

#### `[...slug]` 예시를 SSR용으로 수정

SSR 페이지는 `getStaticPaths()`를 사용할 수 없으므로 props를 받을 수 없습니다. [이전 예시](#예시-여러-레벨의-동적-페이지)는 객체에서 `slug` 매개변수의 값을 조회하여 SSR 모드에 맞게 조정할 수 있습니다. 라우트가 루트 ("/")에 있으면 `slug` 매개변수는 `undefined`가 됩니다. 값이 객체에 존재하지 않으면 404 페이지로 리디렉션합니다.

```astro title="src/pages/[...slug].astro"
---
const pages = [
  {
    slug: undefined,
    title: "Astro 스토어",
    text: "Astro 스토어에 오신 것을 환영합니다!",
  },
  {
    slug: "products",
    title: "Astro 제품",
    text: "여러분을 위한 다양한 제품이 준비되어 있습니다.",
  },
  {
    slug: "products/astro-handbook",
    title: "궁극적인 Astro 핸드북",
    text: "Astro를 배우고 싶다면 이 책을 꼭 읽어야 합니다.",
  },
];

const { slug } = Astro.params;
const page = pages.find((page) => page.slug === slug);
if (!page) return Astro.redirect("/404");
const { title, text } = page;
---
<html>
  <head>
    <title>{title}</title>
  </head>
  <body>
    <h1>{title}</h1>
    <p>{text}</p>
  </body>
</html>
```

## 리디렉션

사이트 구조가 변경되어 영구적으로 또는 인증된 라우트에 로그인하는 등의 작업에 대한 응답으로 독자를 새 페이지로 리디렉션해야 하는 경우가 있습니다.

Astro 구성에서 [영구적으로 이동된 페이지로 사용자를 리디렉션](#구성된-리디렉션)하는 규칙을 정의할 수 있습니다. 또는 사용자가 사이트를 사용할 때 [동적으로 사용자를 리디렉션](#동적-리디렉션)할 수 있습니다.

### 구성된 리디렉션

<p><Since v="2.9.0" /></p>

Astro 구성에서 [`redirects`](/ko/reference/configuration-reference/#redirects) 값을 사용하여 영구 리디렉션 매핑을 지정할 수 있습니다.

내부 리디렉션의 경우, 이는 이전 라우트 경로에서 새 라우트로의 매핑입니다. Astro v5.2.0부터는 `http` 또는 `https`로 시작하고 [구문 분석할 수 있는](https://developer.mozilla.org/en-US/docs/Web/API/URL/canParse_static) 외부 URL로 리디렉션할 수도 있습니다.

```js title="astro.config.mjs" {4-7}
import { defineConfig } from "astro/config";

export default defineConfig({
  redirects: {
    "/old-page": "/new-page",
    "/blog": "https://example.com/blog"
  }
});
```

이러한 리디렉션은 [파일 기반 라우트와 동일한 우선 순위 규칙](#라우트-우선-순위)을 따르며 프로젝트에서 동일한 이름의 기존 페이지 파일보다 항상 낮은 우선 순위를 갖습니다. 예를 들어 프로젝트에 `src/pages/old-page.astro` 파일이 포함된 경우 `/old-page`는 `/new-page`로 리디렉션되지 않습니다.

새 라우트와 이전 라우트 모두 동일한 매개변수를 포함하는 한 동적 라우트가 허용됩니다. 예를 들면 다음과 같습니다.

```js
{
  "/blog/[...slug]": "/articles/[...slug]"
}
```

SSR 또는 정적 어댑터를 사용하면 값을 객체로 제공하여 새 `destination` 외에 `status` 코드를 지정할 수도 있습니다.

```js title="astro.config.mjs" {5-8}
import { defineConfig } from "astro/config";

export default defineConfig({
  redirects: {
    "/old-page": {
      status: 302,
      destination: "/new-page"
    },
    "/news": {
      status: 302,
      destination: "https://example.com/news"
    }
  }
});
```

`astro build`를 실행하면 Astro는 기본적으로 [meta refresh](https://developer.mozilla.org/ko/docs/Web/HTML/Element/meta#%EC%98%88%EC%A0%9C) 태그가 있는 HTML 파일을 출력합니다. 지원되는 어댑터는 대신 리디렉션과 함께 호스트의 구성 파일을 작성합니다.

상태 코드는 기본적으로 `301`입니다. HTML 파일로 빌드하는 경우 상태 코드는 서버에서 사용되지 않습니다.

### 동적 리디렉션

`Astro` 전역에서 `Astro.redirect` 메서드를 사용하면 다른 페이지로 동적으로 리디렉션할 수 있습니다. 쿠키에서 세션을 가져와 사용자가 로그인했는지 확인한 후에 이 작업을 수행할 수 있습니다.

```astro title="src/pages/account.astro" {8}
---
import { isLoggedIn } from "../utils";

const cookie = Astro.request.headers.get("cookie");

// 사용자가 로그인하지 않은 경우 로그인 페이지로 리디렉션합니다.
if (!isLoggedIn(cookie)) {
  return Astro.redirect("/login");
}
---
```

Astro는 온디맨드 렌더링시 [HTML 스트리밍](/ko/guides/on-demand-rendering/#html-스트리밍)을 사용하기 때문에, 리디렉션은 자식 컴포넌트에서가 아닌, 페이지 수준에서 수행되어야 합니다.

## URL 재작성 (Rewrites)

<p><Since v="4.13.0" /></p>

URL 재작성은 브라우저를 다른 페이지로 리디렉션하지 않고 다른 라우트를 제공할 수 있도록 합니다. 브라우저는 URL 표시줄에 원래 주소를 표시하지만, 대신 [`Astro.rewrite()`](/ko/reference/api-reference/#rewrite)에 제공된 URL의 콘텐츠를 표시합니다.

:::tip
영구적으로 이동한 콘텐츠 또는 새 URL이 있는 다른 페이지로 사용자를 안내하려면 (예: 로그인 후 사용자 대시보드), 대신 [리디렉션](#리디렉션)을 사용하세요.
:::

URL 재작성은 두 개의 다른 소스 파일을 유지 관리할 필요 없이 여러 경로 (예: `/products/shoes/men/` 및 `/products/men/shoes/`)에서 동일한 콘텐츠를 표시하는 데 유용할 수 있습니다.

URL 재작성은 SEO 목적과 사용자 경험에도 유용합니다. 이를 통해 방문자를 다른 페이지로 리디렉션하거나 404 상태를 반환해야 하는 콘텐츠를 표시할 수 있습니다. URL 재작성의 일반적인 용도 중 하나는 다양한 언어 변형에 대해 동일한 현지화된 콘텐츠를 표시하는 것입니다.

다음 예제에서는 `/es-CU/` (쿠바 스페인어) URL 경로를 방문했을 때 페이지의 `/es/` 버전을 렌더링하기 위해 URL 재작성을 사용합니다. 방문자가 `/es-cu/articles/introduction` URL로 이동하면 Astro는 `src/pages/es/articles/introduction.astro` 파일에서 생성된 콘텐츠를 렌더링합니다.

```astro title="src/pages/es-cu/articles/introduction.astro"
---
return Astro.rewrite("/es/articles/introduction");
---
```

엔드포인트 파일에서 `context.rewrite()`를 사용하여 다른 페이지로 경로를 재지정합니다.

```js title="src/pages/api.js"
export function GET(context) {
  if (!context.locals.allowed) {
    return context.rewrite("/");
  }
}
```

`Astro.rewrite()`에 전달된 URL이 런타임 오류를 발생시키면 Astro는 개발 환경에서 오버레이 오류를 표시하고 프로덕션 환경에서는 500 상태 코드를 반환합니다. URL이 프로젝트에 존재하지 않으면 404 상태 코드가 반환됩니다.

예를 들어 이커머스의 제품이 더 이상 제공되지 않음을 나타내기 위해 `/404` 페이지를 렌더링하도록 의도적으로 URL 재작성을 생성할 수 있습니다.

```astro title="src/pages/[item].astro"
---
const { item } = Astro.params;

if (!itemExists(item)) {
  return Astro.rewrite("/404");
}
---
``` 

HTTP 응답 상태에 따라 조건부로 URL을 재작성하여 존재하지 않는 URL을 방문할 때 사이트의 특정 페이지를 표시할 수도 있습니다.

```js title="src/middleware.mjs"
export const onRequest = async (context, next) => {
  const response = await next();
  if (response.status === 404) {
    return context.rewrite("/");
  }
  return response;
}
``` 

지정된 URL 재작성 경로의 콘텐츠를 표시하기 전에 `Astro.rewrite()` 함수는 새로운 완전한 렌더링 단계를 트리거합니다. 이렇게 하면 새 라우트/요청에 대한 모든 미들웨어가 다시 실행됩니다.

<ReadMore>자세한 내용은 [`Astro.rewrite()` API 참조](/ko/reference/api-reference/#rewrite)를 확인하세요.</ReadMore>

## 라우트 우선 순위

정의된 여러 라우트가 동일한 URL 경로를 빌드하려고 시도할 수 있습니다. 예를 들어, 이러한 모든 라우트는 `/posts/create`를 빌드할 수 있습니다.

<FileTree>
- src/pages/
  - [...slug].astro
  - posts/
    - create.astro
    - [page].astro
    - [pid].ts
    - [...slug].astro
</FileTree>

Astro는 페이지를 빌드하는 데 어떤 라우트를 사용해야 하는지 알아야 합니다. 이를 위해 다음 규칙에 따라 순서를 정렬합니다.

- Astro의 [예약된 라우트](#예약된-라우트)
- 경로 세그먼트가 많은 라우트는 덜 구체적인 라우트보다 우선합니다. 위 예에서 `/posts/` 아래의 모든 라우트는 루트의 `/[...slug].astro`보다 우선합니다.
- 경로 매개변수가 없는 정적 라우트는 동적 라우트보다 우선합니다. 예를 들어 `/posts/create.astro`는 예시의 다른 모든 라우트보다 우선합니다.
- 명명된 매개변수를 사용하는 동적 라우트는 나머지 매개변수보다 우선합니다. 예를 들어 `/posts/[page].astro`는 `/posts/[...slug].astro`보다 우선합니다.
- 미리 렌더링된 동적 라우트는 서버의 동적 라우트보다 우선합니다.
- 엔드포인트는 페이지보다 우선합니다.
- 파일 기반 라우트는 리디렉션보다 우선합니다.
- 위의 규칙 중 어느 것도 순서를 결정하지 않는 경우, 라우트는 Node 설치의 기본 로케일을 기준으로 알파벳순으로 정렬됩니다.

위 예시를 바탕으로, 요청된 URL을 HTML을 빌드하는 데 사용되는 라우트에 매칭하는 규칙의 몇 가지 예시는 다음과 같습니다.

- `pages/posts/create.astro` - `/posts/create`만 빌드합니다.
- `pages/posts/[pid].ts` - `/posts/abc`, `/posts/xyz` 등을 빌드합니다. 하지만 `/posts/create`는 빌드하지 않습니다.
- `pages/posts/[page].astro` - `/posts/1`, `/posts/2` 등을 빌드합니다. 하지만 `/posts/create`, `/posts/abc` 또는 `/posts/xyz`는 빌드하지 않습니다.
- `pages/posts/[...slug].astro` - `/posts/1/2`, `/posts/a/b/c` 등을 빌드합니다. 하지만 `/posts/create`, `/posts/1`, `/posts/abc` 등은 빌드하지 않습니다.
- `pages/[...slug].astro` - `/abc`, `/xyz`, `/abc/xyz` 등을 빌드합니다. 하지만 `/posts/create`, `/posts/1`, `/posts/abc` 등은 빌드하지 않습니다.

### 예약된 라우트

내부 라우트가 사용자 정의 또는 통합 정의 라우트보다 우선해야 Astro 기능이 작동합니다. 다음은 Astro의 예약된 라우트입니다.

- `_astro/`: CSS 문서, 번들링된 클라이언트 스크립트, 최적화된 이미지 및 모든 Vite 자산을 포함하여 모든 정적 자산을 클라이언트에 제공합니다.
- `_server_islands/`: [서버 아일랜드](/ko/guides/server-islands/)로 연기된 동적 컴포넌트를 제공합니다.
- `_actions/`: 정의된 [액션](/ko/guides/actions/)을 제공합니다.

## 페이지네이션

Astro는 여러 페이지로 분할해야 하는 대규모 데이터 컬렉션에 대한 내장 페이지네이션을 지원합니다. Astro는 이전/다음 페이지 URL, 총 페이지 수 등을 포함한 일반적인 페이지네이션 속성을 생성합니다.

페이지네이션된 라우트 이름은 표준 동적 라우트와 동일한 `[대괄호]` 구문을 사용해야 합니다. 예를 들어, 파일 이름 `/astronauts/[page].astro`는 `/astronauts/1`, `/astronauts/2` 등에 대한 라우트를 생성하며, 여기서 `[page]`는 생성된 페이지 번호입니다.

다음과 같이 `paginate()` 함수를 사용하여 값 배열에 대한 이러한 페이지를 생성할 수 있습니다.

```astro /{ (paginate) }/ /paginate\\(.*\\);/ /(?<=const.*)(page)/ /page\\.[a-zA-Z]+/
---
// src/pages/astronauts/[page].astro
export function getStaticPaths({ paginate }) {
  const astronautPages = [
    { astronaut: "Neil Armstrong" },
    { astronaut: "Buzz Aldrin" },
    { astronaut: "Sally Ride" },
    { astronaut: "John Glenn" },
  ];
  
  // astronauts 배열로부터 페이지를 생성하며, 각 페이지에는 2개의 항목이 표시됩니다.
  return paginate(astronautPages, { pageSize: 2 });
}
// 페이지네이션된 모든 데이터는 "page" prop으로 전달됩니다.
const { page } = Astro.props;
---
<!-- 현재 페이지 번호를 표시합니다. `Astro.params.page`를 사용할 수도 있습니다! -->
<h1>Page {page.currentPage}</h1>
<ul>
  <!-- astronaut 정보 배열을 나열합니다. -->
  {page.data.map(({ astronaut }) => <li>{astronaut}</li>)}
</ul>
```

이는 페이지당 2개의 항목으로 다음 페이지를 생성합니다.

- `/astronauts/1` - 1페이지: "Neil Armstrong" 및 "Buzz Aldrin" 표시
- `/astronauts/2` - 2페이지: "Sally Ride" 및 "John Glenn" 표시

### `page` prop

`paginate()` 함수를 사용하면 각 페이지는 `page` prop을 통해 데이터를 전달받습니다. `page` prop에는 페이지를 빌드하고 페이지 간 링크를 생성하는 데 사용할 수 있는 유용한 속성이 많이 있습니다.

```ts
interface Page<T = any> {
	/** `paginate()` 함수에 전달한 데이터의 페이지 조각을 포함하는 배열입니다. */
	data: T[];
	/** 메타데이터 */
	/** 0부터 시작하는 페이지의 첫 번째 항목 수입니다. */
	start: number;
	/** 0부터 시작하는 페이지의 마지막 항목 수입니다. */
	end: number;
	/** 총 결과 수입니다. */
	total: number;
	/** 1부터 시작하는 현재 페이지 번호입니다. */
	currentPage: number;
	/** 페이지당 항목 수입니다. (기본값: 10) */
	size: number;
	/** 마지막 페이지 번호입니다. */
	lastPage: number;
	url: {
		/** 현재 페이지의 URL입니다. */
		current: string;
		/** 이전 페이지의 URL입니다. (있는 경우) */
		prev: string | undefined;
		/** 다음 페이지의 URL입니다. (있는 경우) */
		next: string | undefined;
		/** 첫 페이지의 URL입니다. (현재 페이지가 첫 페이지가 아닌 경우) */
		first: string | undefined;
		/** 마지막 페이지의 URL입니다. (현재 페이지가 마지막 페이지가 아닌 경우) */
		last: string | undefined;
	};
}
```

다음 예제는 페이지 간 이동 링크와 함께 페이지의 현재 정보를 표시합니다.

```astro /(?<=const.*)(page)/ /page\\.[a-zA-Z]+(?:\\.(?:prev|next|first|last))?/
---
// src/pages/astronauts/[page].astro
// 이전 예제와 동일한 `{ astronaut }` 객체 목록을 페이지로 나눕니다.
export function getStaticPaths({ paginate }) { /* ... */ }
const { page } = Astro.props;
---
<h1>현재 페이지: {page.currentPage}</h1>
<ul>
  {page.data.map(({ astronaut }) => <li>{astronaut}</li>)}
</ul>
{page.url.first ? <a href={page.url.first}>첫 페이지</a> : null}
{page.url.prev ? <a href={page.url.prev}>이전 페이지</a> : null}
{page.url.next ? <a href={page.url.next}>다음 페이지</a> : null}
{page.url.last ? <a href={page.url.last}>마지막 페이지</a> : null}
```

<ReadMore>[페이지네이션의 `page` prop](/ko/reference/routing-reference/#페이지네이션-page-prop)에 대해 자세히 알아보세요.</ReadMore>

### 중첩된 페이지네이션

페이지네이션의 고급 사용 사례는 **중첩된 페이지네이션**입니다. 이는 페이지네이션이 다른 동적 라우트 매개변수와 결합될 때 발생합니다. 중첩된 페이지네이션을 사용하여 페이지네이션된 컬렉션을 일부 속성 또는 태그별로 그룹화할 수 있습니다.

예를 들어, 페이지네이션된 Markdown 게시물을 일부 태그별로 그룹화하려면 다음 URL과 일치하는 `/src/pages/[tag]/[page].astro` 페이지를 생성하여 중첩된 페이지네이션을 사용합니다.

- `/red/1` (tag=red)
- `/red/2` (tag=red)
- `/blue/1` (tag=blue)
- `/green/1` (tag=green)

중첩된 페이지네이션은 `getStaticPaths()`에서 각 그룹에 대해 `paginate()` 결과의 배열을 반환하여 작동합니다.

다음 예제에서는 위에 나열된 URL을 빌드하기 위해 중첩된 페이지네이션을 구현합니다.

```astro /(?:[(]|=== )(tag)/ "params: { tag }," /const [{ ]*(page|params)/
---
// src/pages/[tag]/[page].astro
export function getStaticPaths({ paginate }) {
  const allTags = ["red", "blue", "green"];
  const allPosts = Object.values(import.meta.glob("../pages/post/*.md", { eager: true }));
  // 모든 태그에 대해 `paginate()` 결과를 반환합니다.
  // Astro가 결과가 어떤 태그 그룹에 대한 것인지 알 수 있도록
  // `{ params: { tag }}`를 `paginate()`에 전달해야 합니다.
  return allTags.flatMap((tag) => {
    const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === tag);
    return paginate(filteredPosts, {
      params: { tag },
      pageSize: 10
    });
  });
}

const { page } = Astro.props;
const params = Astro.params;
```

## 페이지 제외

`src/pages`의 페이지 또는 디렉터리를 빌드에서 제외하려면 이름 앞에 밑줄 (`_`)을 붙이면 됩니다. `_` 접두사가 붙은 파일은 라우터에서 인식되지 않으며 `dist/` 디렉터리에 배치되지 않습니다.

이를 사용하여 페이지를 일시적으로 비활성화하고, 테스트, 유틸리티 및 컴포넌트를 관련 페이지와 동일한 폴더에 넣을 수도 있습니다.

이 예시에서는 `src/pages/index.astro` 및 `src/pages/projects/project1.md`만 페이지 라우트 및 HTML 파일로 빌드됩니다.

<FileTree>
- src/pages/
  - _hidden-directory/
    - page1.md
    - page2.md
  - _hidden-page.astro
  - **index.astro**
  - projects/
    - _SomeComponent.astro
    - _utils.js
    - **project1.md**
</FileTree>
